iT邦幫忙

2024 iThome 鐵人賽

DAY 24
0
Python

用 Python 打造你的 Discord BOT系列 第 24

[Day 24] 部屬 (二):Render

  • 分享至 

  • xImage
  •  

今天終於要真的把 Discord BOT 部屬上去了!

進度

如果去掉 Replit,我覺得 Render 的部屬步驟最簡單,所以擺在第一個介紹,GCP 等明天再繼續介紹。

Render

大家也可以參考我去年的去年鐵人賽的文章 XD

Render 是一個提供專門部屬服務的平台,基本上使用者只要準備好程式碼,並設定一下環境變數與啟動指令,就可以輕鬆地部屬自己的服務了。除此之外,一旦 Github 上的程式碼有更新,就會自動觸發重新部屬,不用再自己寫 Github Actions 等 CI/CD 的設定,非常的方便。

Render 的免費額度

昨天有提到,免費額度與條件很重要,所以這此先說明一下 Render 的規定。

Web services 每個月有 750 小時的免費額度 (官方說明),換句話說,如果只有一個服務,那就絕對不會超過額度,可以安心地把它當作一個免費平台使用。

就算不小心超過 (假如同時有多個服務上線的話),這些服務也只會先暫停,不會立刻向使用者收費,如果使用者想要在這個月繼續啟動服務才需要額外付費。

另外,在 Pricing 頁面中的 Compute pricing 也有列出 Web Service 的價格與規格:

Render 部屬步驟

1. 準備要部屬的 Github Repository

在此以 Replit 上的公開專案為例,在 Github 上準備以下三個檔案:

  • main.py:Discord BOT 主程式
  • keep_alive.py:簡單的後端 server
  • requirements.txt:Python 套件清單 (部屬時需要)
# main.py

import os
import discord
from keep_alive import keep_alive

intents = discord.Intents.default()
intents.message_content = True
client = discord.Client(intents=intents)

@client.event
async def on_ready():
    print('We have logged in as {0.user}'.format(client))

@client.event
async def on_message(message):
    if message.author == client.user:
        return
    if message.content.startswith('$hello'):
        await message.channel.send('Hello!')

try:
  token = os.getenv("TOKEN") or ""
  if token == "":
    raise Exception("Please add your token to the Secrets pane.")
  keep_alive()
  client.run(token)
except discord.HTTPException as e:
    if e.status == 429:
        print(
            "The Discord servers denied the connection for making too many requests"
        )
        print(
            "Get help from https://stackoverflow.com/questions/66724687/in-discord-py-how-to-solve-the-error-for-toomanyrequests"
        )
    else:
        raise e
# keep_alive.py

from flask import Flask
from threading import Thread

app = Flask('')

@app.route('/')
def main():
    return '<h1>Bot is awake</h1>'

def run():
    app.run(host="0.0.0.0", port=8080)

def keep_alive():
    server = Thread(target=run)
    server.start()
# requirements.txt

discord.py
flask

想特別提一下,在 main.py 中是使用 os.getenv("TOKEN") 來取得 Discord BOT 的 Token,這樣就可以避免把 Token 上傳到 Github 上。

2. 設定 Render 服務

準備好程式碼後,就可以來設定 Render 了。

(1) 進入 Render (註冊的部分跳過,建議用 Github 帳號註冊)

(2) 選擇 Web Service

點擊「+ New」按鈕,選擇 Web Service。

(3) 選擇要部屬的 Github Repository

選擇後,點擊右下的「Connect」按鈕。

如果是第一次使用 Render,則需要先授與 Github 的權限給 Render,才會看到 Repository 的選項。

(4) 設定啟動指令

接下來會看到很多設定,大部分都不用改,但是啟動指令要自己設定。

python main.py

(5) 選擇方案

要記得修改方案,選擇 Free 的那一個。

(6) 設定環境變數

最後就是設定環境變數,把 Discord BOT 的 Token 加上去,這樣啟動時才能讀取到 Token。

最後,點擊最下面的「Deploy Web Service」按鈕,開始部屬。

3. 部屬

接著就會看到部屬時的 Log

如果有看到 discord.py 的 Log 訊息,以及 Flask 啟動成功的 Log 訊息 (Running on http://127.0.0.1:8080),就代表啟動成功了。

此時可以看到 Discord BOT 上線了,也可以對指令有回應。

設定 UptimeRobot

光是上面那樣還不夠,我們還需要使用 UptimeRobot 來確保這個 Web Service 不會休眠。

設定之前,要先確認一下部屬的網址,網址會在標題的下方:

預設會是 名稱 + .onrender.com

點進去就會看到自己設定的畫面:

UptimeRobot 的設定步驟非常簡單。步驟如下:

1. 進入 UptimeRobot (註冊的部分跳過)

進入 UptimeRobot 後,點擊右上的「+ New monitor」按鈕。

2. 設定要監控的網站

填寫先前在 Render 所看到的 Web Service 的 URL。時間間隔就維持預設的 5 分鐘一次即可。(更短的話要付費才有)

設定完成後,點擊左下的「Create monitor」按鈕,就完成啦!

補充

一開始,我有嘗試過不額外開啟新的 thread 去執行後端 server,單純只是執行 Discord BOT 主程式。結果是:剛部屬完成時,Discord BOT 可以正常運作,但隨後 Render 檢查發現沒有設定對外的 Port (後端 server 一定會有),所以就自行把這個程式關閉了。

所以,在 Render 部屬 Discord BOT 時,另外在一個 thread 上執行後端 server 是必要的手段。

小結

今天介紹了如何部屬 Discord BOT 在 Render 上,並搭配 UptimeRobot 來確保 Discord BOT 不會下線。


上一篇
[Day 23] 部屬 (一):部屬觀念 與 Replit 美好的過去
下一篇
[Day 25] 部屬 (三):GCP (上)
系列文
用 Python 打造你的 Discord BOT31
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言